package com.lfy.modules.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lfy.modules.blog.cache.AuthCache;
import com.lfy.modules.blog.domain.AuthorityEntity;
import com.lfy.modules.blog.domain.RoleAuthorityContactEntity;
import com.lfy.modules.blog.domain.RouteEntity;
import com.lfy.modules.blog.domain.dto.role.AuthDTO;
import com.lfy.modules.blog.domain.vo.auth.AuthAllVO;
import com.lfy.modules.blog.domain.vo.role.SaveRouteByRoleDTO;
import com.lfy.modules.blog.mapper.AuthorityEntityMapper;
import com.lfy.modules.blog.service.AuthorityService;
import com.lfy.modules.blog.service.RoleAuthorityContactService;
import com.lfy.modules.blog.service.RouteService;
import com.lfy.modules.common.domain.R;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author 吕飞扬
* @description 针对表【authority】的数据库操作Service实现
* @createDate 2024-04-03 01:14:55
*/
@Service
public class AuthorityServiceImpl extends ServiceImpl<AuthorityEntityMapper, AuthorityEntity>
    implements AuthorityService {
    @Resource
    private RouteService routeService;
    @Resource
    private RoleAuthorityContactService roleAuthorityContactService;
    @Override
    public List<AuthAllVO> getAuthAll() {
        List<AuthorityEntity> list = this.list(null);
        List<RouteEntity> routeEntities = routeService.list(null);
        ArrayList<AuthAllVO> authAllVOS = new ArrayList<>();
        List<AuthorityEntity> nullResult = list.stream().filter(item -> Objects.isNull(item.getRouteId())).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(nullResult)){
            AuthAllVO authAllVO = new AuthAllVO();
            authAllVO.setRouteName("未知来源");
            authAllVO.setAuthList(nullResult.stream().map(item -> {
                AuthAllVO.Auth auth = new AuthAllVO.Auth();
                BeanUtils.copyProperties(item, auth);
                return auth;
            }).collect(Collectors.toList()));
            authAllVOS.add(authAllVO);
        }
        // 按routeId分组
        Map<Long, List<AuthAllVO.Auth>> map = list.stream().filter(item -> Objects.nonNull(item.getRouteId())).collect(Collectors.groupingBy(AuthorityEntity::getRouteId, Collectors.mapping(item -> {
            AuthAllVO.Auth auth = new AuthAllVO.Auth();
            BeanUtils.copyProperties(item, auth);
            return auth;
        }, Collectors.toList())));

        map.forEach((k, v) -> {
            AuthAllVO authAllVO = new AuthAllVO();
            for (RouteEntity routeEntity : routeEntities) {
                if (routeEntity.getId().equals(k)) {
                    authAllVO.setRouteName(routeEntity.getRouteName());
                    authAllVO.setAuthList(v);
                    authAllVOS.add(authAllVO);
                }
            }
        });
        return authAllVOS;
    }

    @Override
    public R<Set<Long>> getAuthIdByRoleId(Long id) {
        List<RoleAuthorityContactEntity> list = this.roleAuthorityContactService.list(new LambdaQueryWrapper<RoleAuthorityContactEntity>().eq(RoleAuthorityContactEntity::getRoleId, id));
        if(CollectionUtils.isEmpty(list)){
            return R.success();
        }
        Set<Long> set = list.stream().map(RoleAuthorityContactEntity::getAuthorityId).collect(Collectors.toSet());
        return R.success(set);
    }

    @Override
    public R<Void> addAuthByRoleId(AuthDTO dto) {
        Set<Long> authIds = dto.getAuthIds();
        List<RoleAuthorityContactEntity> params = authIds.stream().map(item -> {
            RoleAuthorityContactEntity entity = new RoleAuthorityContactEntity();
            entity.setRoleId(dto.getRoleId());
            entity.setAuthorityId(item);
            return entity;
        }).collect(Collectors.toList());
        this.roleAuthorityContactService.saveBatch(params);
        AuthCache.addAuthByRoleId(dto.getRoleId(),dto.getAuthIds());
        return R.success();
    }

    @Override
    public R<Void> removeAuthByRoleId(AuthDTO dto) {
        Set<Long> authIds = dto.getAuthIds();
        this.roleAuthorityContactService.remove(new LambdaQueryWrapper<RoleAuthorityContactEntity>().and(item-> item.eq(RoleAuthorityContactEntity::getRoleId, dto.getRoleId()).in(RoleAuthorityContactEntity::getAuthorityId, authIds)));
        AuthCache.removeAuthByRoleId(dto.getRoleId(),dto.getAuthIds());
        return R.success();
    }
}




